package com.hkpickup.character;

import java.io.*;

public class Utility {
	public static final String toHexString(long value, int numOfBytes) {
		int numOfChars=numOfBytes<<1;
		String string=Long.toHexString(value).toUpperCase();
		for (int i=numOfChars-string.length(); i>0; i--) {
			string="0"+string;
		}
		if (numOfChars<0) {
			return string;
		} else if (numOfChars==0) {
			return "";
		} else {
			return string.substring(string.length()-numOfChars, string.length());
		}
	}

	public static final String toHexString(byte octets[]) {
		if (octets!=null) {
			StringBuffer hexString=new StringBuffer();
			for (int i=0; i<octets.length; i++) {
				hexString.append(toHexString(octets[i], 1));
			}
			return hexString.toString();
		} else {
			return null;
		}
	}

	public static final int parseInt(String s) {
		try {
			return Integer.parseInt(s, 16);
		} catch (NumberFormatException e) {
			return -1;
		}
	}
	
	public static final long parseLong(String s) {
		try {
			return Long.parseLong(s, 16);
		} catch (NumberFormatException e) {
			return -1;
		}
	}

	public static final byte[] toBytes(String hexString) {
		if (hexString==null) {
			return null;
		} else {
			byte buffer[]=null;
			if (hexString.length()%2!=0) {
				hexString="0"+hexString;
			}
			buffer=new byte[hexString.length()>>1];
			for (int i=0; i<buffer.length; i++) {
				buffer[i]=(byte)parseInt(hexString.substring(i<<1, (i<<1)+2));
			}
			return buffer;
		}
	}

//	public static int readInt(InputStream in, int len) throws IOException, MessageFormatException {
//		int x = 0x00000000;
//		int shiftwidth = 0;
//
//		for (int loop=len-1; loop>=0; loop--) {
//			int b = in.read();
//			if (b == -1) {
//				//throw new MessageFormatException("End of Input stream before integer read");
//				throw new EOFException();
//			}
//
//			shiftwidth = 8 * loop;
//			x |= (b << shiftwidth);
//		}
//		return x;
//	}

	public static void writeIntTo(int i, int len, OutputStream out) throws IOException {
		//byte[]b = new byte[len];
		int mask = 0, sw = 0;		   // AND mask, shiftwidth

		//for(int loop= 0; loop<len; loop++)
		//		b[loop] = (byte) 0x00;

		for(int loop=0; loop<len; loop++) {
			sw = ((len-1) - loop) * 8;
			mask = 0x000000ff << sw;
			out.write((byte) ((i & mask) >>> sw));
		}
	}

    
	public static byte[] readBytes(InputStream in, int length) throws IOException {
		byte octets[]=null;
      
		if (length>0) {
			int octet=0;
			octets=new byte[length];
			for (int i=0; i<octets.length; i++) {
				octet=in.read();
				if (octet==-1) {
					throw new EOFException();
				} else {
                    			octets[i]=(byte)octet;
				}
			}
		}
		return octets;
	}

/*
	public static byte[] readBytes(InputStream in, int length) throws IOException, MessageFormatException {
		if (length>0) {
			byte octets[]=new byte[length];

			length=in.read(octets);
			if (length==-1) {
				throw new EOFException();
			} else if (length!=octets.length) {
				throw new MessageFormatException("length != "+octets.length);
			}

			return octets;
		} else {
			return null;
		}
	}
*/

	public static void writeBytesTo(byte octets[], int length ,OutputStream out) throws IOException {
		if (length>0 && octets!=null && octets.length>0) {
			if (length>octets.length) {
				length=octets.length;
			}
			out.write(octets, 0, length);
		}
	}

	public static void writeBytesTo(byte octets[], OutputStream out) throws IOException {
		if (octets!=null && octets.length>0) {
			out.write(octets, 0, octets.length);
		}
	}

	public static final byte[] toIRABytes(String string) {
                if (string==null) {
                        return null;
                } else if (string.length()==0) {
                        return new byte[0];
                } else {
                        try {
				byte octets[]=string.getBytes("UTF-16BE");
                                byte tempOctets[]=new byte[octets.length];
                                int gsmCount=0;
                                byte gsmOctets[]=null;
                                int unicode=0;
                                for (int i=0; i<octets.length; i+=2) {
                                        unicode=((octets[i]<<8)&0x0000ff00);
                                        unicode|=(octets[i+1]&0x000000ff);
                                        switch (unicode) {
                                                case 0x0040: tempOctets[gsmCount++]=0x00; break;
                                                case 0x00A3: tempOctets[gsmCount++]=0x01; break;
                                                case 0x0024: tempOctets[gsmCount++]=0x02; break;
                                                case 0x00A5: tempOctets[gsmCount++]=0x03; break;
                                                case 0x00E8: tempOctets[gsmCount++]=0x04; break;
                                                case 0x00E9: tempOctets[gsmCount++]=0x05; break;
                                                case 0x00F9: tempOctets[gsmCount++]=0x06; break;
                                                case 0x00EC: tempOctets[gsmCount++]=0x07; break;
                                                case 0x00F2: tempOctets[gsmCount++]=0x08; break;
                                                case 0x00E7: tempOctets[gsmCount++]=0x09; break;
                                                case 0x00D8: tempOctets[gsmCount++]=0x0B; break;
                                                case 0x00F8: tempOctets[gsmCount++]=0x0C; break;
                                                case 0x00C5: tempOctets[gsmCount++]=0x0E; break;
                                                case 0x00E5: tempOctets[gsmCount++]=0x0F; break;

                                                case 0x0394: tempOctets[gsmCount++]=0x10; break;
                                                case 0x005F: tempOctets[gsmCount++]=0x11; break;
                                                case 0x03A6: tempOctets[gsmCount++]=0x12; break;
                                                case 0x0393: tempOctets[gsmCount++]=0x13; break;
                                                case 0x039B: tempOctets[gsmCount++]=0x14; break;
                                                case 0x03A9: tempOctets[gsmCount++]=0x15; break;
                                                case 0x03A0: tempOctets[gsmCount++]=0x16; break;
                                                case 0x03A8: tempOctets[gsmCount++]=0x17; break;
                                                case 0x03A3: tempOctets[gsmCount++]=0x18; break;
                                                case 0x0398: tempOctets[gsmCount++]=0x19; break;
                                                case 0x039E: tempOctets[gsmCount++]=0x1A; break;
                                                case 0x00A0: tempOctets[gsmCount++]=0x1B; break;
                                                case 0x00C6: tempOctets[gsmCount++]=0x1C; break;
                                                case 0x00E6: tempOctets[gsmCount++]=0x1D; break;
                                                case 0x00DF: tempOctets[gsmCount++]=0x1E; break;
                                                case 0x00C9: tempOctets[gsmCount++]=0x1F; break;

                                                case 0x00A4: tempOctets[gsmCount++]=0x24; break;

                                                case 0x00A1: tempOctets[gsmCount++]=0x40; break;

                                                case 0x00C4: tempOctets[gsmCount++]=0x5B; break;
                                                case 0x00D6: tempOctets[gsmCount++]=0x5C; break;
                                                case 0x00D1: tempOctets[gsmCount++]=0x5D; break;
                                                case 0x00DC: tempOctets[gsmCount++]=0x5E; break;
                                                case 0x00A7: tempOctets[gsmCount++]=0x5F; break;

                                                case 0x00BF: tempOctets[gsmCount++]=0x60; break;

                                                case 0x00E4: tempOctets[gsmCount++]=0x7B; break;
                                                case 0x00F6: tempOctets[gsmCount++]=0x7C; break;
                                                case 0x00F1: tempOctets[gsmCount++]=0x7D; break;
                                                case 0x00FC: tempOctets[gsmCount++]=0x7E; break;
                                                case 0x00E0: tempOctets[gsmCount++]=0x7F; break;

                                                case 0x000C: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x0A; break;
                                                case 0x005E: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x14; break;
                                                case 0x007B: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x28; break;
                                                case 0x007D: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x29; break;
                                                case 0x005C: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x2F; break;
                                                case 0x005B: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x3C; break;
                                                case 0x007E: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x3D; break;
                                                case 0x005D: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x3E; break;
                                                case 0x007C: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x40; break;
                                                case 0x20AC: tempOctets[gsmCount++]=0x1B; tempOctets[gsmCount++]=0x65; break;

                                                default:
                                                        if (unicode>0x7A) {
                                                                // replace the unrecognized with a space
                                                                tempOctets[gsmCount++]=0x20;
                                                        } else {
                                                                tempOctets[gsmCount++]=(byte)(unicode&0x000000ff);
                                                        }
                                                        break;
                                        }
                                        gsmOctets=new byte[gsmCount];
                                        System.arraycopy(tempOctets, 0, gsmOctets, 0, gsmCount);
                                }
                                return gsmOctets;
                        } catch (Exception e) {
                                e.printStackTrace();
                                return null;
                        }
                }	
	}

	public static final byte[] parseIRABytes(String ira) {
		if (ira==null) {
			return null;
		} else if (ira.length()==0) {
			return new byte[0];
		} else {
			try {
				int length=ira.length();
				byte tempOctets[]=new byte[length];
				String octet=null;
				byte gsmOctet=0;
				int i=0;
				int unicodeCount=0;
				byte unicodeOctets[]=null;
				while (i<length) {
					octet=ira.charAt(i)+""+ira.charAt(i+1);
					gsmOctet=(byte)(0xff&Integer.parseInt(octet, 16));
					switch (gsmOctet) {
						case 0x00: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x40; break;
						case 0x01: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xA3; break;
						case 0x02: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x24; break;
						case 0x03: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xA5; break;
						case 0x04: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xE8; break;
						case 0x05: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xE9; break;
						case 0x06: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xF9; break;
						case 0x07: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xEC; break;
						case 0x08: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xF2; break;
						case 0x09: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xE7; break;
						case 0x0B: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xD8; break;
						case 0x0C: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xF8; break;
						case 0x0E: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xC5; break;
						case 0x0F: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xE5; break;
						
						case 0x10: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0x94; break;
						case 0x11: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x5F; break;
						case 0x12: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0xA6; break;
						case 0x13: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0x93; break;
						case 0x14: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0x9B; break;
						case 0x15: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0xA9; break;
						case 0x16: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0xA0; break;
						case 0x17: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0xA8; break;
						case 0x18: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0xA3; break;
						case 0x19: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0x98; break;
						case 0x1A: tempOctets[unicodeCount++]=0x03; tempOctets[unicodeCount++]=(byte)0x9E; break;
						
						case 0x1B:
						if (i+2<ira.length()) {
						i+=2;
						octet=ira.charAt(i)+""+ira.charAt(i+1);
						gsmOctet=(byte)(0xff&Integer.parseInt(octet, 16));
						switch (gsmOctet) {
						 case 0x0A: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x0C; break;
						 case 0x14: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x5E; break;
						 case 0x28: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x7B; break;
						 case 0x29: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x7D; break;
						 case 0x2F: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x5C; break;
						 case 0x3C: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x5B; break;
						 case 0x3D: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x7E; break;
						 case 0x3E: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x5D; break;
						 case 0x40: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=0x7C; break;
						 case 0x65: tempOctets[unicodeCount++]=0x20; tempOctets[unicodeCount++]=(byte)0xAC; break;
						 default: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xA0; i-=2; break;
						}
						} else {
						tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xA0;
						}
						break;
						
						case 0x1C: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xC6; break;
						case 0x1D: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xE6; break;
						case 0x1E: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xDF; break;
						case 0x1F: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xC9; break;
						
						case 0x24: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xA4; break;
						
						case 0x40: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xA1; break;
						
						case 0x5B: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xC4; break;
						case 0x5C: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xD6; break;
						case 0x5D: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xD1; break;
						case 0x5E: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xDC; break;
						case 0x5F: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xA7; break;
						
						case 0x60: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xBF; break;
						
						case 0x7B: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xE4; break;
						case 0x7C: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xF6; break;
						case 0x7D: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xF1; break;
						case 0x7E: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xFC; break;
						case 0x7F: tempOctets[unicodeCount++]=0x00; tempOctets[unicodeCount++]=(byte)0xE0; break;
						
						default:
						tempOctets[unicodeCount++]=0x00;
						tempOctets[unicodeCount++]=gsmOctet;
						break;
					}
					i+=2;
				}
				unicodeOctets=new byte[unicodeCount];
				System.arraycopy(tempOctets, 0, unicodeOctets, 0, unicodeCount);
				return unicodeOctets;
			} catch (NumberFormatException e) {
				e.printStackTrace();
				return null;
			}
		}
	}
}
